#include "valparamslincmds.h"
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
#include <limits.h>
#include <string.h>

using namespace std;

#define MIN_CANT_PARAMS 2
#define MAX_CANT_PARAMS 6
#define MIN_CANT_JUGS 2
#define MAX_CANT_JUGS 6

bool ValParamsLinCmds::bParsearParams(int argc, char* argv[], int &p_iCantJugadores, string &p_sArchXmlDelMapa,
	string &p_sArchDebug, string &p_sArchTiradas) {

	ostringstream t_ossMensaje;
	int t_iCantDebugs = 0;
	bool t_bHelp = false;
	bool t_b = false;

	if (argc < MIN_CANT_PARAMS) {
		t_ossMensaje << "No se han especificado parámetros";
	} else if (argc > MAX_CANT_PARAMS) {
		t_ossMensaje << "No se pueden especificar más de " << (MAX_CANT_PARAMS - 1) << " parámetros";
	} else {

		t_b = true;

		for (int i = 1; ((t_b) && (i < argc)); i++) {

			if (strcmp(argv[i], "-h") == 0) {
				t_b = t_bHelp = bParsearParamHelp(i, t_ossMensaje);
			} else if (i == IND_DEL_PARAM_CANT_JUG) {

				t_b = bParsearParamCantJugadores(argv[i], p_iCantJugadores, t_ossMensaje);

				if (t_b) {
					p_sArchXmlDelMapa = ((argc) >= (i + IND_DEL_PARAM_XML_DEL_MAPA)) ? argv[++i] : "";
					t_b = bParsearParamArchXmlDelMapa(p_sArchXmlDelMapa, t_ossMensaje);
				}

			} else if ((i > IND_DEL_PARAM_XML_DEL_MAPA) && (strcmp(argv[i], "-d") == 0)
				&& (t_iCantDebugs == 0)) {

				++t_iCantDebugs;

				p_sArchDebug = ((argc) >= (i + IND_DEL_PARAM_XML_DEL_MAPA)) ? argv[++i] : "";
				t_b = bParsearParamArchDebug(p_sArchDebug, t_ossMensaje);

				if (t_b) {
					p_sArchTiradas = ((argc) >= (i + IND_DEL_PARAM_XML_DEL_MAPA)) ? argv[++i] : "";
					t_b = bParsearParamArchTiradas(p_sArchTiradas, t_ossMensaje);
				}

			} else {
				t_ossMensaje << argv[i] << " no es un parámetro válido";
				t_b = false;
			}
		}
	}

	if (!t_b) {
		cout << endl;
		cout << t_ossMensaje.str() << endl;
		cout << "Especificar ./riskserver -h le proporcionará ayuda" << endl << endl;
	} else if (t_bHelp) {
		cout << endl;
		cout << "Para poner en marcha un nuevo partido:" << endl << endl;
		cout << "./riskserver <cantidad de jugadores (entre 2 y 6)> <archivo xml del mapa>" << endl;
		cout << "[-d <archivo xml de jugadas> <archivo de tiradas>]" << endl << endl;
		cout << "para obtener ayuda:" << endl << endl;
 		cout << "./riskserver -h" << endl << endl;
		t_b = false;
	}

	return t_b;
}

bool ValParamsLinCmds::bParsearParamCantJugadores(string p_sCantJugadores, int &p_iCantJugadores, ostringstream &p_ossMensaje) {

	char *t_pcUltProc = NULL;
	bool t_b = false;
	unsigned int t_uiCantJugadores;

	t_uiCantJugadores = strtoul(p_sCantJugadores.c_str(), &t_pcUltProc, 10);

	if (p_sCantJugadores == "") {
		p_ossMensaje << "No se ha indicado la cantidad de jugadores";
	} else if (t_pcUltProc != (p_sCantJugadores.c_str() + p_sCantJugadores.length())) {
		p_ossMensaje << "La cantidad de jugadores " << p_sCantJugadores << " no es un número válido";
	} else if ((t_uiCantJugadores == ULONG_MAX) || (t_uiCantJugadores < MIN_CANT_JUGS)
		|| (t_uiCantJugadores > MAX_CANT_JUGS)) {
		p_ossMensaje << "La cantidad de jugadores debe ser un número entre " << MIN_CANT_JUGS << " y " << MAX_CANT_JUGS;
	} else {
		p_iCantJugadores = t_uiCantJugadores;
		t_b = true;
	}

	return t_b;
}

bool ValParamsLinCmds::bParsearParamArchXmlDelMapa(string &p_sArchXmlDelMapa, ostringstream &p_ossMensaje) {

	bool t_b = false;
	ifstream t_ifsArch(p_sArchXmlDelMapa.c_str(), ios::in);

	if ((p_sArchXmlDelMapa == "") || (p_sArchXmlDelMapa == "-d")) {
		p_ossMensaje << "No se ha indicado el archivo XML del mapa";
	} else if (!t_ifsArch) {
		p_ossMensaje << "No se puede abrir el archivo " << p_sArchXmlDelMapa;
	} else {
		t_ifsArch.close();
		t_b = true;
	}

	return t_b;
}

bool ValParamsLinCmds::bParsearParamArchDebug(string &p_sArchDebug, ostringstream &p_ossMensaje) {

	bool t_b = false;
	ifstream t_ifsArch(p_sArchDebug.c_str(), ios::in);

	if (p_sArchDebug == "") {
		p_ossMensaje << "No se ha indicado el archivo debug";
	} else if (!t_ifsArch) {
		p_ossMensaje << "No se puede abrir el archivo " << p_sArchDebug;
	} else {
		t_ifsArch.close();
		t_b = true;
	}

	return t_b;
}

bool ValParamsLinCmds::bParsearParamArchTiradas(string &p_sArchTiradas, ostringstream &p_ossMensaje) {

	bool t_b = false;
	ifstream t_ifsArch(p_sArchTiradas.c_str(), ios::in);

	if (p_sArchTiradas == "") {
		p_ossMensaje << "No se ha indicado el archivo con las tiradas de dados";
	} else if (!t_ifsArch) {
		p_ossMensaje << "No se puede abrir el archivo " << p_sArchTiradas;
	} else {
		t_ifsArch.close();
		t_b = true;
	}

	return t_b;
}

bool ValParamsLinCmds::bParsearParamHelp(int p_iIndParamHelp, ostringstream &p_ossMensaje) {

	bool t_b = false;

	if (p_iIndParamHelp != IND_DEL_PARAM_HELP) {
		p_ossMensaje << "Si se especifica el parámetro de -h, debe ser el único";
	} else {
		t_b = true;
	}

	return t_b;
}
